
import { AxiosRequestConfig, AxiosPromise, AxiosResponse } from './types/index';
import { parseHeaders } from './helpers/headers';
import { createError } from './helpers/error'

/** 原生ajax发送请求 */
export default function xhr(config: AxiosRequestConfig): AxiosPromise {
  return new Promise((resolve, reject ) => {
      const { data = null, url, method = 'get', headers = {}, responseType, timeout } = config;
      const request = new XMLHttpRequest();

      // 请求响应类型
      if ( responseType ) {
        request.responseType =  responseType
      }

      //超时时间设置
      if( timeout ) {
        request.timeout = timeout
      }

      request.open(method.toLocaleUpperCase(), url!, true);
    
      //设置请求头： 必须在open和send方法之间调用： 
      //原因send() 方法被调用后，服务端已获得头部和状态
      Object.keys(headers).forEach(name => {
        // data为空，不需要设置content-type，因为processHeaders中默认添加了content-type，此处可删除
        if(data === null && name.toLocaleLowerCase() === 'content-type') {
          delete headers[name];
        }else {
          request.setRequestHeader(name, headers[name])
        }
      })
      
      request.send(data)
    
      request.onreadystatechange = function() {
        if(request.readyState !== 4) {
          return
        }
        console.log("request.status==", request.status)
        // 当出现网络错误或者超时错误的时候，status都为 0
        if(request.status === 0) {
          return
        }

        // header字符串转JSON对象
        const responseHeaders = parseHeaders(request.getAllResponseHeaders());
        const responseData = responseType && responseType !== 'text' ? request.response : request.responseText;
        const response: AxiosResponse = {
          data: responseData,
          status: request.status,
          statusText: request.statusText,
          headers: responseHeaders,
          config,
          request
        }
        
        // resolve(response);
        handerResponse(response)
      }
      
      // 非200-300状态码处理
      function handerResponse(response: AxiosResponse):void {
        if (response.status >= 200 && response.status < 300) {
          resolve(response)
        } else {
          reject(createError(
            `Request failed with status code ${response.status}`,
             config,
             null, 
             request,
             response
          ))
        }
      }

      // 网络请求等错误
      request.onerror = function() {
        reject(createError('Network Error', config, '0', request))
      }

      // 超时
      request.ontimeout = function() {
        reject(createError(`Timeout of ${timeout} ms exceeded`, config, 'ECONNABORTED',request))
      }
  })
}